/*
 *
 * Copyright (C) 2012 Walter Lütgenau
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package offset.nodes.server.embedded.view;

import java.awt.CardLayout;
import java.awt.Frame;
import java.io.File;
import java.io.IOException;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.DocumentFilter.FilterBypass;
import offset.nodes.server.embedded.NodesConfig;

/**
 *
 * @author Walter L�tgenau
 */
public class InstallerDialog extends javax.swing.JDialog {
    public static final String CARD_CONFIGURATION = "configuration";
    public static final String CARD_PROGRESS = "progress";
    public static final String CARD_SHUTDOWN = "shutdown";

    JFileChooser chooser = null;
    NodesConfig config;
    SwingWorker startup;

    /** Creates new form StartupTypeSelector */
    public InstallerDialog(NodesConfig config, SwingWorker startup, boolean alreadyRunning) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, UnsupportedLookAndFeelException {
        super((Frame) null, true);
        this.config = config;
        this.startup = startup;
        
        StartupLookAndFeelManager.setLookAndFeel();
        
        initComponents();

        installDirTextfield.setText(config.getInstallDir().getPath());
        repositoryTextfield.setText(config.getRepository().getPath());
        portTextfield.setText(new Integer(config.getPort()).toString());

        chooser = new JFileChooser(installDirTextfield.getText());
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

        if (alreadyRunning) {
            ResourceBundle bundle = ResourceBundle.getBundle("offset/nodes/server/embedded/view/Embedded");
            nextButton.setText(bundle.getString("installer.stop"));
            
            ((CardLayout) setupPanel.getLayout()).show(setupPanel, CARD_SHUTDOWN);
        }
        else
            ((CardLayout) setupPanel.getLayout()).show(setupPanel, CARD_CONFIGURATION);
    }

    public void close() {
        setVisible(false);
        dispose();
    }

    public JTextArea getProgressMessages() {
        return progressTextArea;
    }

    protected void execute() {
        ((CardLayout) setupPanel.getLayout()).show(setupPanel, CARD_PROGRESS);
        nextButton.setEnabled(false);
        startup.execute();
    }

    public NodesConfig getConfig() {
        return this.config = new NodesConfig(new File(installDirTextfield.getText()), new File(repositoryTextfield.getText()), Integer.parseInt(portTextfield.getText()), showBrowser.isSelected());
    }

    class NumericDocumentFilter extends DocumentFilter {

        @Override
        public void insertString(FilterBypass fb, int offset, String value, AttributeSet attr) throws BadLocationException {
            fb.insertString(offset, value.replaceAll("[^0-9]", ""), attr);
        }

        @Override
        public void replace(FilterBypass fb, int offset, int length, String value, AttributeSet attrs) throws BadLocationException {
            fb.replace(offset, length, value.replaceAll("[^0-9]", ""), attrs);
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane2 = new javax.swing.JScrollPane();
        jEditorPane1 = new javax.swing.JEditorPane();
        startupTypeButtonGroup = new javax.swing.ButtonGroup();
        setupPanel = new javax.swing.JPanel();
        progressPanel = new javax.swing.JPanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        progressTextArea = new javax.swing.JTextArea();
        progressBar = new javax.swing.JProgressBar();
        configurationPanel = new javax.swing.JPanel();
        installDirTextfield = new javax.swing.JTextField();
        installDirButton = new javax.swing.JButton();
        installDirLabel = new javax.swing.JLabel();
        repositoryLabel = new javax.swing.JLabel();
        repositoryTextfield = new javax.swing.JTextField();
        repositoryButton = new javax.swing.JButton();
        portLabel = new javax.swing.JLabel();
        portTextfield = new javax.swing.JTextField();
        ((AbstractDocument) portTextfield.getDocument()).setDocumentFilter(new NumericDocumentFilter());
        showBrowser = new javax.swing.JCheckBox();
        shutdownPanel = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        buttonPanel = new javax.swing.JPanel();
        nextButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();

        jScrollPane2.setViewportView(jEditorPane1);

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setBackground(javax.swing.UIManager.getDefaults().getColor("Button.background"));
        setLocationByPlatform(true);

        setupPanel.setLayout(new java.awt.CardLayout());

        progressTextArea.setColumns(20);
        progressTextArea.setFont(new java.awt.Font("Monospaced", 0, 11)); // NOI18N
        progressTextArea.setForeground(new java.awt.Color(0, 102, 255));
        progressTextArea.setLineWrap(true);
        progressTextArea.setRows(5);
        progressTextArea.setWrapStyleWord(true);
        jScrollPane3.setViewportView(progressTextArea);

        progressBar.setIndeterminate(true);

        javax.swing.GroupLayout progressPanelLayout = new javax.swing.GroupLayout(progressPanel);
        progressPanel.setLayout(progressPanelLayout);
        progressPanelLayout.setHorizontalGroup(
            progressPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, progressPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(progressPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 685, Short.MAX_VALUE)
                    .addComponent(progressBar, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 685, Short.MAX_VALUE))
                .addContainerGap())
        );
        progressPanelLayout.setVerticalGroup(
            progressPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, progressPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 179, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(39, 39, 39))
        );

        setupPanel.add(progressPanel, "progress");

        installDirButton.setText("...");
        installDirButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                selectInstallationDirectory(evt);
            }
        });

        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("offset/nodes/server/embedded/view/Embedded"); // NOI18N
        installDirLabel.setText(bundle.getString("configuration.installDir")); // NOI18N

        repositoryLabel.setText(bundle.getString("configuration.repository")); // NOI18N

        repositoryButton.setText("...");
        repositoryButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                selectRepository(evt);
            }
        });

        portLabel.setText(bundle.getString("configuration.port")); // NOI18N

        showBrowser.setSelected(true);
        showBrowser.setText(bundle.getString("configuration.startBrowser")); // NOI18N

        javax.swing.GroupLayout configurationPanelLayout = new javax.swing.GroupLayout(configurationPanel);
        configurationPanel.setLayout(configurationPanelLayout);
        configurationPanelLayout.setHorizontalGroup(
            configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(configurationPanelLayout.createSequentialGroup()
                .addGap(37, 37, 37)
                .addGroup(configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(repositoryLabel)
                    .addComponent(installDirLabel)
                    .addComponent(portLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(configurationPanelLayout.createSequentialGroup()
                        .addGroup(configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(installDirTextfield, javax.swing.GroupLayout.DEFAULT_SIZE, 444, Short.MAX_VALUE)
                            .addComponent(repositoryTextfield, javax.swing.GroupLayout.DEFAULT_SIZE, 444, Short.MAX_VALUE))
                        .addGap(10, 10, 10)
                        .addGroup(configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(repositoryButton)
                            .addComponent(installDirButton)))
                    .addGroup(configurationPanelLayout.createSequentialGroup()
                        .addComponent(portTextfield, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(showBrowser)))
                .addGap(60, 60, 60))
        );
        configurationPanelLayout.setVerticalGroup(
            configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(configurationPanelLayout.createSequentialGroup()
                .addGroup(configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(configurationPanelLayout.createSequentialGroup()
                        .addGap(87, 87, 87)
                        .addComponent(repositoryButton))
                    .addGroup(configurationPanelLayout.createSequentialGroup()
                        .addGap(53, 53, 53)
                        .addGroup(configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(installDirTextfield, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(installDirButton)
                            .addComponent(installDirLabel))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(repositoryTextfield, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(repositoryLabel))
                        .addGap(18, 18, 18)
                        .addGroup(configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(portTextfield, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(portLabel)
                            .addComponent(showBrowser))))
                .addContainerGap(108, Short.MAX_VALUE))
        );

        setupPanel.add(configurationPanel, "configuration");

        jLabel1.setText(bundle.getString("shutdown.message")); // NOI18N

        javax.swing.GroupLayout shutdownPanelLayout = new javax.swing.GroupLayout(shutdownPanel);
        shutdownPanel.setLayout(shutdownPanelLayout);
        shutdownPanelLayout.setHorizontalGroup(
            shutdownPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(shutdownPanelLayout.createSequentialGroup()
                .addGap(64, 64, 64)
                .addComponent(jLabel1)
                .addContainerGap(351, Short.MAX_VALUE))
        );
        shutdownPanelLayout.setVerticalGroup(
            shutdownPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(shutdownPanelLayout.createSequentialGroup()
                .addGap(52, 52, 52)
                .addComponent(jLabel1)
                .addContainerGap(190, Short.MAX_VALUE))
        );

        setupPanel.add(shutdownPanel, "shutdown");

        nextButton.setText(bundle.getString("installer.next")); // NOI18N
        nextButton.setPreferredSize(new java.awt.Dimension(67, 23));
        nextButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                execute(evt);
            }
        });

        cancelButton.setText(bundle.getString("installer.cancel")); // NOI18N
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancel(evt);
            }
        });

        javax.swing.GroupLayout buttonPanelLayout = new javax.swing.GroupLayout(buttonPanel);
        buttonPanel.setLayout(buttonPanelLayout);
        buttonPanelLayout.setHorizontalGroup(
            buttonPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, buttonPanelLayout.createSequentialGroup()
                .addContainerGap(555, Short.MAX_VALUE)
                .addComponent(nextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cancelButton)
                .addContainerGap())
        );
        buttonPanelLayout.setVerticalGroup(
            buttonPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, buttonPanelLayout.createSequentialGroup()
                .addContainerGap(12, Short.MAX_VALUE)
                .addGroup(buttonPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(nextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cancelButton))
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(setupPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(buttonPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(setupPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 256, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(46, Short.MAX_VALUE))
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap(256, Short.MAX_VALUE)
                    .addComponent(buttonPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void selectInstallationDirectory(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectInstallationDirectory
        chooser.setSelectedFile(new File(installDirTextfield.getText()));
        if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            installDirTextfield.setText(chooser.getSelectedFile().getPath());
            repositoryTextfield.setText(installDirTextfield.getText() + File.separator + config.getRepository().getName());
        }
}//GEN-LAST:event_selectInstallationDirectory

    private void selectRepository(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectRepository
        chooser.setSelectedFile(new File(repositoryTextfield.getText()));
        if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            repositoryTextfield.setText(chooser.getSelectedFile().getPath());
        }
}//GEN-LAST:event_selectRepository

    private void cancel(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancel
        close();
    }//GEN-LAST:event_cancel

    private void execute(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_execute
        execute();
    }//GEN-LAST:event_execute

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    NodesConfig config = new NodesConfig(new File("a/b"), new File("a/b/nodes"), 8040, true);
                    SwingWorker worker = new SwingWorker<Void, Void>() {

                        @Override
                        protected Void doInBackground() throws Exception {
                            System.out.println("Hurray");
                            return null;
                        }

                    };
                    InstallerDialog dialog = new InstallerDialog(config, worker, false);
                    dialog.setVisible(true);
                } catch (ClassNotFoundException ex) {
                    Logger.getLogger(InstallerDialog.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IllegalAccessException ex) {
                    Logger.getLogger(InstallerDialog.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InstantiationException ex) {
                    Logger.getLogger(InstallerDialog.class.getName()).log(Level.SEVERE, null, ex);
                } catch (UnsupportedLookAndFeelException ex) {
                    Logger.getLogger(InstallerDialog.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel buttonPanel;
    private javax.swing.JButton cancelButton;
    private javax.swing.JPanel configurationPanel;
    private javax.swing.JButton installDirButton;
    private javax.swing.JLabel installDirLabel;
    private javax.swing.JTextField installDirTextfield;
    private javax.swing.JEditorPane jEditorPane1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JButton nextButton;
    private javax.swing.JLabel portLabel;
    private javax.swing.JTextField portTextfield;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JPanel progressPanel;
    private javax.swing.JTextArea progressTextArea;
    private javax.swing.JButton repositoryButton;
    private javax.swing.JLabel repositoryLabel;
    private javax.swing.JTextField repositoryTextfield;
    private javax.swing.JPanel setupPanel;
    private javax.swing.JCheckBox showBrowser;
    private javax.swing.JPanel shutdownPanel;
    private javax.swing.ButtonGroup startupTypeButtonGroup;
    // End of variables declaration//GEN-END:variables

}
